<!--
 * @Author: licongwei
 * @Date: 2022-03-17 14:32:41
 * @Description:星空动效
-->
<template>
  <div class="star-sky">
    <canvas ref="canvas"></canvas>
  </div>
</template>
<script lang="ts">
import { defineComponent, onBeforeUnmount, onMounted, ref } from 'vue'
interface IStar {
  x: number
  y: number
  z: number
  o: string
}
export default defineComponent({
  name: 'starSky',
  setup() {
    const canvas = ref()
    let c: any = null
    onMounted(() => {
      c = canvas.value.getContext('2d') as CanvasRenderingContext2D
      focalLength = canvas.value.width * 2
      init()
    })

    onBeforeUnmount(() => {
      cancelAnimationFrame(timer)
    })

    let numStars = 2000
    let radius = '0.' + Math.floor(Math.random() * 9) + 1
    let focalLength = 0
    let warp = 0,
      centerX = 0,
      centerY = 0
    let stars: IStar[] = [],
      star: any = {}

    let i
    let animate = true
    let timer = 0
    const init = () => {
      initializeStars()
      executeFrame()
    }
    const executeFrame = () => {
      if (animate) {
        timer = window.requestAnimationFrame(executeFrame)
      }
      moveStars()
      drawStars()
    }

    // 生成星星数组
    const initializeStars = () => {
      centerX = canvas.value.width / 2
      centerY = canvas.value.height / 2

      stars = []
      for (i = 0; i < numStars; i++) {
        star = {
          x: Math.random() * canvas.value.width,
          y: Math.random() * canvas.value.height,
          z: Math.random() * canvas.value.width,
          o: '0.' + Math.floor(Math.random() * 99) + 1
        }
        stars.push(star)
      }
    }
    const moveStars = () => {
      for (i = 0; i < numStars; i++) {
        star = stars[i]
        star.z -= 0.6
        if (star.z <= 0) {
          star.z = canvas.value.width
        }
      }
    }
    const drawStars = () => {
      let pixelX, pixelY, pixelRadius
      if (canvas.value.width != 1920) {
        canvas.value.width = 1920
        canvas.value.height = 1080
        initializeStars()
      }

      if (warp == 0) {
        c.fillStyle = 'rgba(14,14,53,1)' //背景颜色(黑色一些)
        // c.fillStyle = 'rgb(39, 39, 87)' //背景颜色(紫色一些)
        c.fillRect(0, 0, canvas.value.width, canvas.value.height)
      }
      c.fillStyle = 'rgba(182, 255, 255, ' + radius + ')'
      for (i = 0; i < numStars; i++) {
        star = stars[i]

        pixelX = (star.x - centerX) * (focalLength / star.z)
        pixelX += centerX
        pixelY = (star.y - centerY) * (focalLength / star.z)
        pixelY += centerY
        pixelRadius = 1 * (focalLength / star.z)

        c.beginPath()
        // c.fillRect(pixelX, pixelY, pixelRadius, pixelRadius);
        c.arc(pixelX, pixelY, pixelRadius, 0, 2 * Math.PI)

        c.fillStyle = 'rgba(0, 255, 255, ' + star.o + ')'
        c.fill()
      }
    }

    return {
      canvas
    }
  }
})
</script>
<style lang="less" scoped>
.star-sky {
  position: absolute;
  top: 0;
  left: 0;
  // width: 1920px;
  // height: 1080px;
  width: 100%;
  height: 100%;
  z-index: 0;
  canvas {
    width: 100%;
    height: 100%;
    color: rgb(39, 39, 87);
  }
}
</style>
